﻿// Original author contact info: Owen Emlen (owene_1998@yahoo.com)
// Note: other individuals may also have contributed to this code
// Project hosted on CodePlex.com as of 1/10/2009 at http://wpfimageviewer.codeplex.com
using System;
using System.Linq;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Threading;
using System.Windows;
using BrainTechLLC;
using BrainTechLLC.ThreadSafeObjects;
using BrainTechLLC.ImageOperatorsNonAForgeDependent;
using System.Collections.Generic;
using System.Collections.ObjectModel;

namespace BrainTechLLC
{
    [Serializable]
    public class Settings : BaseNotifyPropertyChanged, INotifyPropertyChanged
    {
        [NonSerialized]
        public static ThreadSafeListAndLookup<string, string> _alsoRaisePropertiesLookup;

        [NonSerialized]
        public static Settings Values;

        [NonSerialized]
        public RenderSettings _standardRenderSettings;

        static Settings()
        {
            _alsoRaisePropertiesLookup = new ThreadSafeListAndLookup<string, string>();
            typeof(Settings).WireUpAlsoRaisePropertiesLookup(_alsoRaisePropertiesLookup);
        }


        protected bool _TrackLocationInThumbView;
        protected int _MaxThumbnailImageSources = 12;
        protected double _thumbWidth = 300D;
        protected double _thumbHeight = 240D;
        protected bool _recordTimings;
        protected bool _wantFilterThumbnails;
        protected bool _active = true;
        protected bool _viewerIsTopmost = true;
        protected bool _highQualityThumbs = true;
        protected double _fullWidth = 0D;
        protected double _fullHeight = 0D;
        protected double _fullLeft = 0D;
        protected double _fullTop = 0D;
        protected ThreadSafeListAndLookup<string, KeyFileNameAndOrder> _OrderedFileNames;
        protected WindowState _fullWindowState;
        protected WindowState _ShowMultipleImagesWindowState;
        protected int _MinSizeFilter;
        protected int _MaxSizeFilter = Int32.MaxValue - 1;
        protected WindowState _mainWindowState;
        protected WindowState _DirectoryViewWindowState;
        protected WindowState _FolderExplorerWindowState;
        protected double _scaleFactor = 0.2D;
        protected bool _ConfirmDelete;
        protected bool _ConfirmMultiDelete = true;
        protected double _blurCutoff = 120D;
        protected double _similarityCutoff = 120D;
        protected long _unusedBytesBeforeCleanup = 8000 * 1024;
        protected double _MainGridRow1Height = 400D;
        protected double _minScaleWidth = 200D;
        protected double _minScaleHeight = 200D;
        protected InterpolationMode _interpolationMode = InterpolationMode.Low;
        protected int _MaxTransformedBitmapsInMemory;
        protected int _TransformedToTossWhenMaxReached;
        protected SmoothingMode _smoothingMode = SmoothingMode.None;
        protected int _maxThumbsInMemory = 56;
        protected int _maxAdditionalInfosInMemory = 30;
        public bool _useHSLRounding = false;
        public int _decimalDigitsHSLLuminanceRounding = 2;
        public int _decimalDigitsHSLSaturationRounding = 2;
        protected int _maxBitmapsInMemory = 8;
        protected int _itemsToTossWhenMaxReached = 4;
        protected int _thumbPreloadThreads = 3;
        protected bool _ThumbShowFileDescriptions;
        protected PixelFormat _standardColorPixelFormat = PixelFormat.Format24bppRgb;
        protected bool _showImageInfoBelowThumbs;
        protected bool _showFullViewerDetails1 = true;
        protected bool _showFullViewerDetails2;
        protected bool _evenThumbWidths = true;
        protected bool _showDebugOnThumbs;
        protected int _similarityScaleWidth = 300;
        protected int _similarityScaleHeight = 300;
        protected int _maxFilesInMemory = 64;
        protected double _compareMultipleWidth = 300D;
        protected double _compareMultipleHeight = 300D;
        protected InternalRenderingMethod _internalRendering = InternalRenderingMethod.None;
        protected string _currentFilterCollectionName = string.Empty;
        protected double _mainFormRow0Height = 26;
        protected double _mainFormRow2Height = 28;
        protected double _mainFormRow3Height = 200;
        protected double _mainFormRow4Height = 100;
        protected int _similarityCacheMax = 128;
        protected int _similarityCacheToRemove = 16;
        protected int _maxConcurrentBlurCalcs = 3;
        protected int _resizeWidth = 1024;
        protected int _resizeHeight = 768;
        protected string _resizedFileName;
        protected bool _thumbShowFileDate;
        protected bool _ShowCommandBar = true;
        protected bool _ShowFilters;
        protected bool _thumbShowFileName = true;
        protected bool _thumbShowFileSize;
        protected bool _thumbShowFullPath;
        protected bool _thumbShowDimensions;
        protected bool _sortDescending;
        protected bool _sortDescending2;
        protected bool _showThumbCommandBar = true;
        protected string _sortBy;
        protected string _SortBy2;
        protected int _resizeJpegQuality = 100;
        protected bool _directoriesVisible;
        protected bool _thumbnailsVisible = true;
        protected bool _folderExplorerVisible;
        protected bool _filterExplorerVisible;
        protected bool _FolderListVisible = true;
        protected bool _GroupOrganizerVisible = true;
        protected bool _fullViewerVisible;
        protected Rectangle _directoriesViewLocation;
        protected Rectangle _foldersViewLocation;
        protected Rectangle _showMultipleImagesLocation;
        protected Rectangle _fullViewerLocation;
        protected int _imageSourcesToTossWhenMaxReached = 6;
        protected int _maxImageSourcesInMemory = 10;
        protected int _MaxThumbnailControlsInMemory = 70;
        protected int _GroupOrganizerWidth = 70;
        protected int _FolderListWidth = 70;
        protected int _fileBytesToTossWhenMaxReached = 6;
        protected int _maxFileBytesInMemory = 12;
        protected bool _FolderExplorerTopmost = true;
        protected string _fileNameFilter = string.Empty;
        protected bool _TopCommandBarVisibile = true;

        protected RenderSettings CreateRenderSettings()
        {
            RenderSettings renderSettings = new RenderSettings()
            {
                PixelFormat = StandardColorPixelFormat,
                Interpolation = InterpolationMode,
                Smoothing = SmoothingMode,
                RenderingMethod = InternalRendering
            };

            return renderSettings;
        }

        protected override void BeforePropertyChanged(string propertyName)
        {
            if (propertyName == "StandardColorPixelFormat" ||
                propertyName == "InterpolationMode" ||
                propertyName == "SmoothingMode" ||
                propertyName == "InternalRendering")
            {
                Interlocked.Exchange<RenderSettings>(ref _standardRenderSettings, CreateRenderSettings());
            }
        }

        protected override void AfterPropertyChanged(string propertyName)
        {
            this.CheckAlsoRaise(propertyName, _alsoRaisePropertiesLookup);
            base.AfterPropertyChanged(propertyName);
        }

        public RenderSettings StandardRenderSettings
        {
            get
            {
                if (_standardRenderSettings == null)
                {
                    Interlocked.Exchange<RenderSettings>(ref _standardRenderSettings, CreateRenderSettings());
                }

                return _standardRenderSettings;
            }
        }

        public bool ThumbShowFileDescriptions
        {
            get { return _ThumbShowFileDescriptions; }
            set
            {
                if (_ThumbShowFileDescriptions != value)
                {
                    _ThumbShowFileDescriptions = value;
                    OnPropertyChanged("ThumbShowFileDescriptions");
                }
            }
        }

        public int GroupOrganizerWidth
        {
            get { return _GroupOrganizerWidth; }
            set
            {
                if (_GroupOrganizerWidth != value)
                {
                    _GroupOrganizerWidth = value;
                    OnPropertyChanged("GroupOrganizerWidth");
                }
            }
        }

        public int FolderListWidth
        {
            get { return _FolderListWidth; }
            set
            {
                if (_FolderListWidth != value)
                {
                    _FolderListWidth = value;
                    OnPropertyChanged("FolderListWidth");
                }
            }
        }

        public bool FolderExplorerTopmost
        {
            get { return _FolderExplorerTopmost; }
            set
            {
                if (_FolderExplorerTopmost != value)
                {
                    _FolderExplorerTopmost = value;
                    OnPropertyChanged("FolderExplorerTopmost");
                }
            }
        }

        public bool FolderListVisible
        {
            get { return _FolderListVisible; }
            set
            {
                if (_FolderListVisible != value)
                {
                    _FolderListVisible = value;
                    OnPropertyChanged("FolderListVisible");
                }
            }
        }

        public bool GroupOrganizerVisible
        {
            get { return _GroupOrganizerVisible; }
            set
            {
                if (_GroupOrganizerVisible != value)
                {
                    _GroupOrganizerVisible = value;
                    OnPropertyChanged("GroupOrganizerVisible");
                }
            }
        }

        public int MaxThumbnailControlsInMemory
        {
            get { return _MaxThumbnailControlsInMemory < 30 ? 30 : _MaxThumbnailControlsInMemory; }
            set
            {
                if (_MaxThumbnailControlsInMemory != value)
                {
                    _MaxThumbnailControlsInMemory = value;
                    OnPropertyChanged("MaxThumbnailControlsInMemory");
                }
            }
        }

        public void SaveOrdering<T>(ObservableCollection<T> items, string directory, Func<T, string> transformToString, ThreadSafeListAndLookup<string, KeyFileNameAndOrder> results)
        {
            results.RemoveAll(directory, s => s.Key == directory);
            List<string> itemStrings = items.Select(o => transformToString(o)).ToList();
            //itemStrings.RemoveAll(s => s.EndsWith(".gif", StringComparison.OrdinalIgnoreCase));
            List<KeyFileNameAndOrder> ordering = new List<KeyFileNameAndOrder>();
            for (int n = 0; n < itemStrings.Count; n++)
            {
                KeyFileNameAndOrder order = new KeyFileNameAndOrder()
                {
                    FileName = itemStrings[n],
                    Order = n,
                    Key = directory,
                };
                ordering.Add(order);
            }
            results.AddMultiple(directory, ordering);
        }

        public void SaveOrdering<T>(List<T> items, string directoryToExamine, Func<T, string> transformToString, ThreadSafeListAndLookup<string, KeyFileNameAndOrder> results)
        {
            results.RemoveAll(directoryToExamine, s => s.Key == directoryToExamine);
            List<string> itemStrings = items.Select(o => transformToString(o)).ToList();
            List<KeyFileNameAndOrder> ordering = new List<KeyFileNameAndOrder>();
            for (int n = 0; n < itemStrings.Count; n++)
            {
                KeyFileNameAndOrder order = new KeyFileNameAndOrder()
                {
                    FileName = itemStrings[n],
                    Order = n,
                    Key = directoryToExamine,
                };
                ordering.Add(order);
            }
            results.AddMultiple(directoryToExamine, ordering);
        }

        public ThreadSafeListAndLookup<string, KeyFileNameAndOrder> OrderedFileNames
        {
            get
            {
                if (_OrderedFileNames == null)
                {
                    Interlocked.CompareExchange(ref _OrderedFileNames, new ThreadSafeListAndLookup<string, KeyFileNameAndOrder>(), null);
                }

                return _OrderedFileNames;
            }
            set
            {
                if (_OrderedFileNames != value)
                {
                    _OrderedFileNames = value;
                    OnPropertyChanged("OrderedFileNames");
                }
            }
        }

        public string FileNameFilter
        {
            get { return _fileNameFilter; }
            set
            {
                if (_fileNameFilter != value)
                {
                    _fileNameFilter = value;
                    OnPropertyChanged("FileNameFilter");
                }
            }
        }

        public bool TopCommandBarVisibile
        {
            get { return _TopCommandBarVisibile; }
            set
            {
                if (_TopCommandBarVisibile != value)
                {
                    _TopCommandBarVisibile = value;
                    OnPropertyChanged("TopCommandBarVisibile");
                }
            }
        }


        public int MaxSizeFilter
        {
            get { return _MaxSizeFilter; }
            set
            {
                if (_MaxSizeFilter != value)
                {
                    _MaxSizeFilter = value;
                    OnPropertyChanged("MaxSizeFilter");
                }
            }
        }

        public int MinSizeFilter
        {
            get { return _MinSizeFilter; }
            set
            {
                if (_MinSizeFilter != value)
                {
                    _MinSizeFilter = value;
                    OnPropertyChanged("MinSizeFilter");
                }
            }
        }

        [RaisePropertyChangedForThisPropertyWhenOtherPropertyChanges("ThumbShowFileDate")]
        [RaisePropertyChangedForThisPropertyWhenOtherPropertyChanges("ThumbShowFileName")]
        [RaisePropertyChangedForThisPropertyWhenOtherPropertyChanges("ThumbShowFileSize")]
        [RaisePropertyChangedForThisPropertyWhenOtherPropertyChanges("ThumbShowFullPath")]
        [RaisePropertyChangedForThisPropertyWhenOtherPropertyChanges("ThumbShowDimensions")]
        public bool NoInfoDisplayedBelowThumbs
        {
            get { return !(_thumbShowFileDate || _thumbShowFileName || _thumbShowFileSize || _thumbShowFullPath || _thumbShowDimensions); }
        }

        public int ImageSourcesToTossWhenMaxReached
        {
            get { return _imageSourcesToTossWhenMaxReached; }
            set
            {
                if (_imageSourcesToTossWhenMaxReached != value)
                {
                    _imageSourcesToTossWhenMaxReached = value;
                    OnPropertyChanged("ImageSourcesToTossWhenMaxReached");
                }
            }
        }

        public int MaxTransformedBitmapsInMemory
        {
            get { return _MaxTransformedBitmapsInMemory; }
            set
            {
                if (_MaxTransformedBitmapsInMemory != value)
                {
                    _MaxTransformedBitmapsInMemory = value;
                    OnPropertyChanged("MaxTransformedBitmapsInMemory");
                }
            }
        }

        public int TransformedToTossWhenMaxReached
        {
            get { return _TransformedToTossWhenMaxReached; }
            set
            {
                if (_TransformedToTossWhenMaxReached != value)
                {
                    _TransformedToTossWhenMaxReached = value;
                    OnPropertyChanged("TransformedToTossWhenMaxReached");
                }
            }
        }

        public int MaxThumbnailImageSources
        {
            get { return _MaxThumbnailImageSources; }
            set
            {
                if (_MaxThumbnailImageSources != value)
                {
                    _MaxThumbnailImageSources = value;
                    OnPropertyChanged("MaxThumbnailImageSources");
                }
            }
        }

        public bool TrackLocationInThumbView
        {
            get { return _TrackLocationInThumbView; }
            set
            {
                if (_TrackLocationInThumbView != value)
                {
                    _TrackLocationInThumbView = value;
                    OnPropertyChanged("TrackLocationInThumbView");
                }
            }
        }

        public int MaxAdditionalInfosInMemory
        {
            get { return _maxAdditionalInfosInMemory; }
            set
            {
                if (_maxAdditionalInfosInMemory != value)
                {
                    _maxAdditionalInfosInMemory = value;
                    OnPropertyChanged("MaxAdditionalInfosInMemory");
                }
            }
        }


        public double MainGridRow1Height
        {
            get { return _MainGridRow1Height; }
            set
            {
                if (_MainGridRow1Height != value)
                {
                    _MainGridRow1Height = value;
                    OnPropertyChanged("MainGridRow1Height");
                }
            }
        }

        public bool ConfirmDelete
        {
            get { return _ConfirmDelete; }
            set
            {
                if (_ConfirmDelete != value)
                {
                    _ConfirmDelete = value;
                    OnPropertyChanged("ConfirmDelete");
                }
            }
        }

        public bool ConfirmMultiDelete
        {
            get { return _ConfirmMultiDelete; }
            set
            {
                if (_ConfirmMultiDelete != value)
                {
                    _ConfirmMultiDelete = value;
                    OnPropertyChanged("ConfirmMultiDelete");
                }
            }
        }

        public int MaxImageSourcesInMemory
        {
            get { return _maxImageSourcesInMemory; }
            set
            {
                if (_maxImageSourcesInMemory != value)
                {
                    _maxImageSourcesInMemory = value;
                    OnPropertyChanged("MaxImageSourcesInMemory");
                }
            }
        }

        public int FileBytesToTossWhenMaxReached
        {
            get { return _fileBytesToTossWhenMaxReached; }
            set
            {
                if (_fileBytesToTossWhenMaxReached != value)
                {
                    _fileBytesToTossWhenMaxReached = value;
                    OnPropertyChanged("FileBytesToTossWhenMaxReached");
                }
            }
        }

        public int MaxFileBytesInMemory
        {
            get { return _maxFileBytesInMemory; }
            set
            {
                if (_maxFileBytesInMemory != value)
                {
                    _maxFileBytesInMemory = value;
                    OnPropertyChanged("MaxFileBytesInMemory");
                }
            }
        }

        public Rectangle DirectoriesViewLocation
        {
            get { return _directoriesViewLocation; }
            set
            {
                if (_directoriesViewLocation != value)
                {
                    _directoriesViewLocation = value;
                    OnPropertyChanged("DirectoriesViewLocation");
                }
            }
        }

        public Rectangle FoldersViewLocation
        {
            get { return _foldersViewLocation; }
            set
            {
                if (_foldersViewLocation != value)
                {
                    _foldersViewLocation = value;
                    OnPropertyChanged("FoldersViewLocation");
                }
            }
        }

        public Rectangle ShowMultipleImagesLocation
        {
            get { return _showMultipleImagesLocation; }
            set
            {
                if (_showMultipleImagesLocation != value)
                {
                    _showMultipleImagesLocation = value;
                    OnPropertyChanged("ShowMultipleImagesLocation");
                }
            }
        }

        public Rectangle FullViewerLocation
        {
            get { return _fullViewerLocation; }
            set
            {
                if (_fullViewerLocation != value)
                {
                    _fullViewerLocation = value;
                    OnPropertyChanged("FullViewerLocation");
                }
            }
        }

        public bool FullViewerVisible
        {
            get { return _fullViewerVisible; }
            set
            {
                if (_fullViewerVisible != value)
                {
                    _fullViewerVisible = value;
                    OnPropertyChanged("FullViewerVisible");
                }
            }
        }

        public bool FilterExplorerVisible
        {
            get { return _filterExplorerVisible; }
            set
            {
                if (_filterExplorerVisible != value)
                {
                    _filterExplorerVisible = value;
                    OnPropertyChanged("FilterExplorerVisible");
                }
            }
        }

        public bool FolderExplorerVisible
        {
            get { return _folderExplorerVisible; }
            set
            {
                if (_folderExplorerVisible != value)
                {
                    _folderExplorerVisible = value;
                    OnPropertyChanged("FolderExplorerVisible");
                }
            }
        }

        public bool ThumbnailsVisible
        {
            get { return _thumbnailsVisible; }
            set
            {
                if (_thumbnailsVisible != value)
                {
                    _thumbnailsVisible = value;
                    OnPropertyChanged("ThumbnailsVisible");
                }
            }
        }

        public bool DirectoriesVisible
        {
            get { return _directoriesVisible; }
            set
            {
                if (_directoriesVisible != value)
                {
                    _directoriesVisible = value;
                    OnPropertyChanged("DirectoriesVisible");
                }
            }
        }

        public bool ShowThumbCommandBar
        {
            get { return _showThumbCommandBar; }
            set
            {
                if (_showThumbCommandBar != value)
                {
                    _showThumbCommandBar = value;
                    OnPropertyChanged("ShowThumbCommandBar");
                }
            }
        }

        public int ResizeJpegQuality
        {
            get { return _resizeJpegQuality; }
            set
            {
                if (_resizeJpegQuality != value)
                {
                    _resizeJpegQuality = value;
                    OnPropertyChanged("ResizeJpegQuality");
                }
            }
        }

        public bool ThumbShowFileDate
        {
            get { return _thumbShowFileDate; }
            set
            {
                if (_thumbShowFileDate != value)
                {
                    _thumbShowFileDate = value;
                    OnPropertyChanged("ThumbShowFileDate");
                }
            }
        }

        public string SortBy
        {
            get { return _sortBy; }
            set
            {
                if (_sortBy != value)
                {
                    _sortBy = value;
                    OnPropertyChanged("SortBy");
                }
            }
        }

        public bool SortDescending
        {
            get { return _sortDescending; }
            set
            {
                if (_sortDescending != value)
                {
                    _sortDescending = value;
                    OnPropertyChanged("SortDescending");
                }
            }
        }

        public string SortBy2
        {
            get { return _SortBy2; }
            set
            {
                if (_SortBy2 != value)
                {
                    _SortBy2 = value;
                    OnPropertyChanged("SortBy2");
                }
            }
        }

        public bool SortDescending2
        {
            get { return _sortDescending2; }
            set
            {
                if (_sortDescending2 != value)
                {
                    _sortDescending2 = value;
                    OnPropertyChanged("SortDescending2");
                }
            }
        }

        public bool ThumbShowFileName
        {
            get { return _thumbShowFileName; }
            set
            {
                if (_thumbShowFileName != value)
                {
                    _thumbShowFileName = value;
                    OnPropertyChanged("ThumbShowFileName");
                }
            }
        }

        public bool ThumbShowFileSize
        {
            get { return _thumbShowFileSize; }
            set
            {
                if (_thumbShowFileSize != value)
                {
                    _thumbShowFileSize = value;
                    OnPropertyChanged("ThumbShowFileSize");
                }
            }
        }

        public bool ThumbShowFullPath
        {
            get { return _thumbShowFullPath; }
            set
            {
                if (_thumbShowFullPath != value)
                {
                    _thumbShowFullPath = value;
                    OnPropertyChanged("ThumbShowFullPath");
                }
            }
        }

        public bool ThumbShowDimensions
        {
            get { return _thumbShowDimensions; }
            set
            {
                if (_thumbShowDimensions != value)
                {
                    _thumbShowDimensions = value;
                    OnPropertyChanged("ThumbShowDimensions");
                }
            }
        }

        public string ResizedFileName
        {
            get { return _resizedFileName; }
            set
            {
                if (_resizedFileName != value)
                {
                    _resizedFileName = value;
                    OnPropertyChanged("ResizedFileName");
                }
            }
        }

        public int ResizeWidth
        {
            get { return _resizeWidth; }
            set
            {
                if (_resizeWidth != value)
                {
                    _resizeWidth = value;
                    OnPropertyChanged("ResizeWidth");
                }
            }
        }

        public int ResizeHeight
        {
            get { return _resizeHeight; }
            set
            {
                if (_resizeHeight != value)
                {
                    _resizeHeight = value;
                    OnPropertyChanged("ResizeHeight");
                }
            }
        }

        public int SimilarityCacheMax
        {
            get { return _similarityCacheMax; }
            set
            {
                if (_similarityCacheMax != value)
                {
                    _similarityCacheMax = value;
                    OnPropertyChanged("SimilarityCacheMax");
                }
            }
        }

        public int MaxConcurrentBlurCalcs
        {
            get { return _maxConcurrentBlurCalcs; }
            set
            {
                if (_maxConcurrentBlurCalcs != value)
                {
                    _maxConcurrentBlurCalcs = value;
                    OnPropertyChanged("MaxConcurrentBlurCalcs");
                }
            }
        }

        public int SimilarityCacheToRemove
        {
            get { return _similarityCacheToRemove; }
            set
            {
                if (_similarityCacheToRemove != value)
                {
                    _similarityCacheToRemove = value;
                    OnPropertyChanged("SimilarityCacheToRemove");
                }
            }
        }

        public double MainFormRow0Height
        {
            get { return _mainFormRow0Height; }
            set
            {
                if (_mainFormRow0Height != value)
                {
                    _mainFormRow0Height = value;
                    OnPropertyChanged("MainFormRow0Height");
                }
            }
        }

        public double MainFormRow2Height
        {
            get { return _mainFormRow2Height; }
            set
            {
                if (_mainFormRow2Height != value)
                {
                    _mainFormRow2Height = value;
                    OnPropertyChanged("MainFormRow2Height");
                }
            }
        }

        public double MainFormRow3Height
        {
            get { return _mainFormRow3Height; }
            set
            {
                if (_mainFormRow3Height != value)
                {
                    _mainFormRow3Height = value;
                    OnPropertyChanged("MainFormRow3Height");
                }
            }
        }

        public double MainFormRow4Height
        {
            get { return _mainFormRow4Height; }
            set
            {
                if (_mainFormRow4Height != value)
                {
                    _mainFormRow4Height = value;
                    OnPropertyChanged("MainFormRow4Height");
                }
            }
        }

        public string CurrentFilterCollectionName
        {
            get { return _currentFilterCollectionName; }
            set
            {
                if (_currentFilterCollectionName != value)
                {
                    _currentFilterCollectionName = value;
                    OnPropertyChanged("CurrentFilterCollectionName");
                }
            }
        }

        public InternalRenderingMethod InternalRendering
        {
            get { return _internalRendering; }
            set
            {
                if (_internalRendering != value)
                {
                    _internalRendering = value;
                    OnPropertyChanged("InternalRendering");
                }
            }
        }

        public int SimilarityScaleWidth
        {
            get { return _similarityScaleWidth; }
            set
            {
                if (_similarityScaleWidth != value)
                {
                    _similarityScaleWidth = value;
                    OnPropertyChanged("SimilarityScaleWidth");
                }
            }
        }

        public int SimilarityScaleHeight
        {
            get { return _similarityScaleHeight; }
            set
            {
                if (_similarityScaleHeight != value)
                {
                    _similarityScaleHeight = value;
                    OnPropertyChanged("SimilarityScaleHeight");
                }
            }
        }

        public double CompareMultipleWidth
        {
            get { return _compareMultipleWidth; }
            set
            {
                if (_compareMultipleWidth != value)
                {
                    _compareMultipleWidth = value;
                    OnPropertyChanged("CompareMultipleWidth");
                }
            }
        }

        public double CompareMultipleHeight
        {
            get { return _compareMultipleHeight; }
            set
            {
                if (_compareMultipleHeight != value)
                {
                    _compareMultipleHeight = value;
                    OnPropertyChanged("CompareMultipleHeight");
                }
            }
        }

        public bool ShowDebugOnThumbs
        {
            get { return _showDebugOnThumbs; }
            set
            {
                if (_showDebugOnThumbs != value)
                {
                    _showDebugOnThumbs = value;
                    OnPropertyChanged("ShowDebugOnThumbs");
                }
            }
        }

        public bool ShowFullViewerDetails1
        {
            get { return _showFullViewerDetails1; }
            set
            {
                if (_showFullViewerDetails1 != value)
                {
                    _showFullViewerDetails1 = value;
                    OnPropertyChanged("ShowFullViewerDetails1");
                }
            }
        }

        public bool ShowFullViewerDetails2
        {
            get { return _showFullViewerDetails2; }
            set
            {
                if (_showFullViewerDetails2 != value)
                {
                    _showFullViewerDetails2 = value;
                    OnPropertyChanged("ShowFullViewerDetails2");
                }
            }
        }

        public bool EvenThumbWidths
        {
            get { return _evenThumbWidths; }
            set
            {
                if (_evenThumbWidths != value)
                {
                    _evenThumbWidths = value;
                    OnPropertyChanged("EvenThumbWidths");
                }
            }
        }

        public bool ShowImageInfoBelowThumbs
        {
            get { return _showImageInfoBelowThumbs; }
            set
            {
                if (_showImageInfoBelowThumbs != value)
                {
                    _showImageInfoBelowThumbs = value;
                    OnPropertyChanged("ShowImageInfoBelowThumbs");
                }
            }
        }

        public int ThumbPreloadThreads
        {
            get { return _thumbPreloadThreads; }
            set
            {
                if (_thumbPreloadThreads != value)
                {
                    _thumbPreloadThreads = value;
                    OnPropertyChanged("ThumbPreloadThreads");
                }
            }
        }

        public PixelFormat StandardColorPixelFormat
        {
            get { return _standardColorPixelFormat; }
            set
            {
                if (_standardColorPixelFormat != value)
                {
                    _standardColorPixelFormat = value;
                    OnPropertyChanged("StandardColorPixelFormat");
                }
            }
        }

        public int ItemsToTossWhenMaxReached
        {
            get { return _itemsToTossWhenMaxReached; }
            set
            {
                if (_itemsToTossWhenMaxReached != value)
                {
                    _itemsToTossWhenMaxReached = value;
                    OnPropertyChanged("ItemsToTossWhenMaxReached");
                }
            }
        }

        public int MaxBitmapsInMemory
        {
            get { return _maxBitmapsInMemory; }
            set
            {
                if (_maxBitmapsInMemory != value)
                {
                    _maxBitmapsInMemory = value;
                    OnPropertyChanged("MaxBitmapsInMemory");
                }
            }
        }

        public long UnusedBytesBeforeCleanup
        {
            get { return _unusedBytesBeforeCleanup; }
            set
            {
                if (_unusedBytesBeforeCleanup != value)
                {
                    _unusedBytesBeforeCleanup = value;
                    OnPropertyChanged("UnusedBytesBeforeCleanup");
                }
            }
        }

        public int MaxFilesInMemory
        {
            get { return _maxFilesInMemory; }
            set
            {
                if (_maxFilesInMemory != value)
                {
                    _maxFilesInMemory = value;
                    OnPropertyChanged("MaxFilesInMemory");
                }
            }
        }

        public int MaxThumbsInMemory
        {
            get { return _maxThumbsInMemory; }
            set
            {
                if (_maxThumbsInMemory != value)
                {
                    _maxThumbsInMemory = value;
                    OnPropertyChanged("MaxThumbsInMemory");
                }
            }
        }

        public bool RecordTimings
        {
            get { return _recordTimings; }
            set
            {
                if (_recordTimings != value)
                {
                    _recordTimings = value;
                    OnPropertyChanged("RecordTimings");
                }
            }
        }

        public bool UseHSLRounding
        {
            get
            {
                return _useHSLRounding;
            }
            set
            {
                if (_useHSLRounding != value)
                {
                    _useHSLRounding = value;
                    OnPropertyChanged("UseHSLRounding");
                }
            }
        }


        public int DecimalDigitsHSLLuminanceRounding
        {
            get
            {
                return _decimalDigitsHSLLuminanceRounding;
            }
            set
            {
                if (_decimalDigitsHSLLuminanceRounding != value)
                {
                    _decimalDigitsHSLLuminanceRounding = value;
                    OnPropertyChanged("DecimalDigitsHSLLuminanceRounding");
                }
            }
        }

        public int DecimalDigitsHSLSaturationRounding
        {
            get
            {
                return _decimalDigitsHSLSaturationRounding;
            }
            set
            {
                if (_decimalDigitsHSLSaturationRounding != value)
                {
                    _decimalDigitsHSLSaturationRounding = value;
                    OnPropertyChanged("DecimalDigitsHSLSaturationRounding");
                }
            }
        }


        public double MinScaleWidth
        {
            get { return _minScaleWidth; }
            set
            {
                if (_minScaleWidth != value)
                {
                    _minScaleWidth = value;
                    OnPropertyChanged("MinScaleWidth");
                }
            }
        }

        public double MinScaleHeight
        {
            get { return _minScaleHeight; }
            set
            {
                if (_minScaleHeight != value)
                {
                    _minScaleHeight = value;
                    OnPropertyChanged("MinScaleHeight");
                }
            }
        }

        public InterpolationMode InterpolationMode
        {
            get { return _interpolationMode; }
            set
            {
                if (_interpolationMode != value)
                {
                    _interpolationMode = value;
                    OnPropertyChanged("InterpolationMode");
                }
            }
        }

        public SmoothingMode SmoothingMode
        {
            get { return _smoothingMode; }
            set
            {
                if (_smoothingMode != value)
                {
                    _smoothingMode = value;
                    OnPropertyChanged("SmoothingMode");
                }
            }
        }

        public double SimilarityCutoff
        {
            get { return _similarityCutoff; }
            set
            {
                if (_similarityCutoff != value)
                {
                    _similarityCutoff = value;
                    OnPropertyChanged("SimilarityCutoff");
                }
            }
        }

        public double BlurCutoff
        {
            get { return _blurCutoff; }
            set
            {
                if (_blurCutoff != value)
                {
                    _blurCutoff = value;
                    OnPropertyChanged("BlurCutoff");
                }
            }
        }

        public double ScaleFactor
        {
            get { return _scaleFactor; }
            set
            {
                if (_scaleFactor != value)
                {
                    _scaleFactor = value;
                    OnPropertyChanged("ScaleFactor");
                }
            }
        }

        public double FullLeft
        {
            get { return _fullLeft; }
            set
            {
                if (_fullLeft != value)
                {
                    _fullLeft = value;
                    OnPropertyChanged("FullLeft");
                }
            }
        }

        public double FullTop
        {
            get { return _fullTop; }
            set
            {
                if (_fullTop != value)
                {
                    _fullTop = value;
                    OnPropertyChanged("FullTop");
                }
            }
        }

        public double FullWidth
        {
            get { return _fullWidth; }
            set
            {
                if (_fullWidth != value)
                {
                    _fullWidth = value;
                    OnPropertyChanged("FullWidth");
                }
            }
        }
        public double FullHeight
        {
            get { return _fullHeight; }
            set
            {
                if (_fullHeight != value)
                {
                    _fullHeight = value;
                    OnPropertyChanged("FullHeight");
                }
            }
        }

        public WindowState FullWindowState
        {
            get { return _fullWindowState; }
            set
            {
                if (_fullWindowState != value)
                {
                    _fullWindowState = value;
                    OnPropertyChanged("FullWindowState");
                }
            }
        }

        public WindowState ShowMultipleImagesWindowState
        {
            get { return _ShowMultipleImagesWindowState; }
            set
            {
                if (_ShowMultipleImagesWindowState != value)
                {
                    _ShowMultipleImagesWindowState = value;
                    OnPropertyChanged("ShowMultipleImagesWindowState");
                }
            }
        }

        public WindowState MainWindowState
        {
            get { return _mainWindowState; }
            set
            {
                if (_mainWindowState != value)
                {
                    _mainWindowState = value;
                    OnPropertyChanged("MainWindowState");
                }
            }
        }

        public WindowState DirectoryViewWindowState
        {
            get { return _DirectoryViewWindowState; }
            set
            {
                if (_DirectoryViewWindowState != value)
                {
                    _DirectoryViewWindowState = value;
                    OnPropertyChanged("DirectoryViewWindowState");
                }
            }
        }

        public WindowState FolderExplorerWindowState
        {
            get { return _FolderExplorerWindowState; }
            set
            {
                if (_FolderExplorerWindowState != value)
                {
                    _FolderExplorerWindowState = value;
                    OnPropertyChanged("FolderExplorerWindowState");
                }
            }
        }

        protected Rectangle _window1Size;

        public bool ViewerIsTopmost
        {
            get { return _viewerIsTopmost; }
            set
            {
                if (_viewerIsTopmost != value)
                {
                    _viewerIsTopmost = value;
                    OnPropertyChanged("ViewerIsTopmost");
                }
            }
        }

        public bool HighQualityThumbs
        {
            get { return _highQualityThumbs; }
            set
            {
                if (_highQualityThumbs != value)
                {
                    _highQualityThumbs = value;
                    OnPropertyChanged("HighQualityThumbs");
                }
            }
        }

        public bool ShowCommandBar
        {
            get { return _ShowCommandBar; }
            set
            {
                if (_ShowCommandBar != value)
                {
                    _ShowCommandBar = value;
                    OnPropertyChanged("ShowCommandBar");
                }
            }
        }

        public bool ShowFilters
        {
            get { return _ShowFilters; }
            set
            {
                if (_ShowFilters != value)
                {
                    _ShowFilters = value;
                    OnPropertyChanged("ShowFilters");
                }
            }
        }

        public Rectangle Window1Size
        {
            get { return _window1Size; }
            set
            {
                if (_window1Size != value)
                {
                    _window1Size = value;
                    OnPropertyChanged("Window1Size");
                }
            }
        }

        public double ThumbWidth
        {
            get { return _thumbWidth; }
            set
            {
                if (_thumbWidth != value)
                {
                    _thumbWidth = value;
                    OnPropertyChanged("ThumbWidth");
                }
            }
        }

        public double ThumbHeight
        {
            get { return _thumbHeight; }
            set
            {
                if (_thumbHeight != value)
                {
                    _thumbHeight = value;
                    OnPropertyChanged("ThumbHeight");
                }
            }
        }

        [RaisePropertyChangedForThisPropertyWhenOtherPropertyChanges("ThumbWidth")]
        public double ThumbWidthPlus
        {
            get { return _thumbWidth + 16D; }
        }

        [RaisePropertyChangedForThisPropertyWhenOtherPropertyChanges("ThumbHeight")]
        public double ThumbHeightPlus
        {
            get { return _thumbHeight + 10D; }
        }

        [RaisePropertyChangedForThisPropertyWhenOtherPropertyChanges("ThumbWidth")]
        public double ThumbWidthMinus
        {
            get { return _thumbWidth - 4; }
        }

        [RaisePropertyChangedForThisPropertyWhenOtherPropertyChanges("ThumbHeight")]
        public double ThumbHeightMinus
        {
            get { return _thumbHeight - 4; }
        }

        public bool WantFilterThumbnails
        {
            get { return _wantFilterThumbnails; }
            set
            {
                if (_wantFilterThumbnails != value)
                {
                    _wantFilterThumbnails = value;
                    OnPropertyChanged("WantFilterThumbnails");
                }
            }
        }

        public static Settings LoadSettings(string path)
        {
            if (!File.Exists(path))
                return null;

            byte[] bytes = File.ReadAllBytes(path);
            var settings = bytes.DeserializeFromCompressedBinary(false) as Settings;

            if (settings != null)
                settings._propertyChanged = new FastSmartWeakEvent<PropertyChangedEventHandler>();

            return settings;
        }

        public void SaveSettings(string path)
        {
            byte[] bytes = this.SerializeToCompressedBinary(true);
            File.WriteAllBytes(path, bytes);
        }

        public bool Active
        {
            get
            {
                return _active;
            }
            set
            {
                if (_active != value)
                {
                    _active = value;
                    OnPropertyChanged("Active");
                }
            }
        }

        public void SetThumbWidthAndHeight(double w, double h)
        {
            ThumbWidth = w;
            ThumbHeight = h;
        }
    }
}
